package pl.edu.pw.MidEmu.UI.Components;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import pl.edu.pw.MidEmu.Base.Components.BaseFrame;
import pl.edu.pw.MidEmu.Common.Consts;
import pl.edu.pw.MidEmu.Common.Models.EthernetInterfaceModel;
import pl.edu.pw.MidEmu.UI.Controllers.NetworkConnectivityController;
import pl.edu.pw.MidEmu.UI.Views.NetworkConnectivityView;

/**
 * Frame with GUI for managing connectivity between nodes
 * @author Mateusz Starodab
 *
 */
public class NetworkConnectivityFrame extends BaseFrame<JDialog, NetworkConnectivityController> implements NetworkConnectivityView
{
	private JButton btnOK;
	private MainFrame parent;
	private JPanel pnlCenter;
	private JPanel pnlMain;
	private JPanel pnlSouth;

	private boolean canRun = true;

	public NetworkConnectivityFrame(MainFrame mainFrame)
	{
		this.parent = mainFrame;

		NetworkConnectivityController controller = new NetworkConnectivityController();
		controller.setView(this);
		setController(controller);
		JDialog frame = new JDialog();
		setComponent(frame);

		getComponent().setTitle(Consts.MainFrame_Title + " - " + Consts.NetworkConnectivity_Title);

		getComponent().setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		getComponent().setModal(true);

		pnlMain = new JPanel(new BorderLayout());

		List<EthernetInterfaceModel> ethernetModels = getController().getEthernetInterfaces();

		if (ethernetModels.size() == 0)
		{
			reportNoFreeInterfaces();
		}

		int size = ethernetModels.size() + 1;
		pnlCenter = new JPanel(new GridLayout(size + 1, size, 3, 3));
		pnlCenter.setBorder(BorderFactory.createTitledBorder(Consts.NetworkConnectivity_InterfacesMatrix));

		getComponent().setSize(size * 75, (size + 1) * 55);

		for (int i = 0; i < size + 1; i++)
		{
			for (int j = 0; j < size; j++)
			{
				if (i == 0 && j > 0)
				{
					JLabel lbl = new JLabel(ethernetModels.get(j - 1).getIpAddress());
					addWithBorder(pnlCenter, lbl);
				}
				else if (j == 0 && i > 0)
				{
					if (i == size)
					{
						JLabel lbl = new JLabel("Broadcast");
						addWithBorder(pnlCenter, lbl);
					}
					else
					{
						JLabel lbl = new JLabel(ethernetModels.get(i - 1).getIpAddress());
						addWithBorder(pnlCenter, lbl);
					}
				}
				else if (i != j)
				{
					if (i == size)
					{
						JCheckBox box = new JCheckBox();
						box.setName("0.0.0.0/0_" + ethernetModels.get(j - 1).getIpAddress());
						box.addActionListener(getController());
						box.getModel().setSelected(parent.getController().checkIfEnabled("0.0.0.0/0", ethernetModels.get(j - 1).getIpAddress()));
						addWithBorder(pnlCenter, box);
					}
					else
					{
						JCheckBox box = new JCheckBox();
						box.setName(ethernetModels.get(i - 1).getIpAddress() + "_" + ethernetModels.get(j - 1).getIpAddress());
						box.addActionListener(getController());
						box.getModel().setSelected(parent.getController().checkIfEnabled(ethernetModels.get(i - 1).getIpAddress(), ethernetModels.get(j - 1).getIpAddress()));
						addWithBorder(pnlCenter, box);
					}
				}
				else
				{
					JLabel lbl = new JLabel();
					addWithBorder(pnlCenter, lbl);
				}
			}
		}

		pnlMain.add(pnlCenter, BorderLayout.CENTER);

		pnlSouth = new JPanel(new FlowLayout(FlowLayout.CENTER));

		btnOK = new JButton(Consts.NetworkConnectivity_ButtonOK);
		btnOK.setName(Consts.NetworkConnectivity_ButtonOK);
		btnOK.addActionListener(getController());
		pnlSouth.add(btnOK);

		pnlMain.add(pnlSouth, BorderLayout.SOUTH);

		getComponent().setContentPane(pnlMain);
	}

	private void addWithBorder(JPanel panel, JComponent cmp)
	{
		JPanel tmpPanel = new JPanel();
		tmpPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		tmpPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		tmpPanel.add(cmp);
		panel.add(tmpPanel);
	}

	public boolean canRun()
	{
		return canRun;
	}

	@Override
	public void dispose()
	{
		getComponent().setVisible(false);
		getComponent().dispose();
	}

	@Override
	public List<EthernetInterfaceModel> getRegisteredInterfaces()
	{
		return parent.getController().getRegisteredInterfaces();
	}

	@Override
	public void setConnection(String name, boolean b)
	{
		parent.getController().setConnection(name, b);
	}

	public void reportNoFreeInterfaces()
	{
		JOptionPane.showMessageDialog(getComponent(), "Can't show network connectivity frame because there are no network interfaces.\nPlease add interfaces through Settings/Network menu.", "No free interfaces", JOptionPane.ERROR_MESSAGE);
		canRun = false;
	}
}
